package com.ljwm.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.ljwm.bootbase.enums.ResultEnum;
import com.ljwm.bootbase.exception.LogicException;
import com.ljwm.bootbase.security.JwtKit;
import com.ljwm.bootbase.security.SecurityKit;
import com.ljwm.entity.User;
import com.ljwm.mapper.UserMapper;
import com.ljwm.model.dto.LoginForm;
import com.ljwm.model.vo.ResultMe;
import com.ljwm.security.JwtUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * BootBaseDemo Created by yunqisong on 2018-05-22.
 * FOR:
 */
@Slf4j
@Service
public class UserService implements ApplicationRunner {

    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * 公共验证逻辑实现
     *
     * @param loginForm
     * @return
     */
    private JwtUser validate(LoginForm loginForm) {
        return Optional
            .ofNullable(loginForm)
            .map(form -> new UsernamePasswordAuthenticationToken(form.getUsername(), form.getPassword()))
            .map(upToken -> authenticationManager.authenticate(upToken))
            .map(authentication -> {
                if (!authentication.isAuthenticated())
                    throw new LogicException(ResultEnum.BAD_CREDENTIALS);
                SecurityContextHolder.getContext().setAuthentication(authentication);
                log.debug("登陆成功, 为该用户创建Token: {} ", loginForm);
                return (JwtUser) authentication.getPrincipal();
            })
            .get();
    }

    /**
     * 构造Me中信息
     *
     * @param jwtUser
     * @return
     */
    public ResultMe meAdmin(JwtUser jwtUser) {

        return Optional
            .ofNullable(jwtUser)
            .map(user -> new ResultMe()
                .setUsername(user.getUsername())
                .setId(user.getId())
            )
            .get();
    }

    /**
     * 后台登录
     *
     * @param loginForm
     * @return
     */
    public ResultMe loginAdmin(LoginForm loginForm) {

        return Optional
            .ofNullable(loginForm)
            .map(this::validate)
            .map(jwtUser -> meAdmin(jwtUser).setToken(JwtKit.generateToken(jwtUser)))
            .get();
    }

    @Autowired
    private UserMapper userMapper;

    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {
        List<User> userList = userMapper.selectList(new EntityWrapper<>());
        if (CollUtil.isEmpty(userList)) {
            userMapper.insert(
                new User()
                    .setUsername("admin")
                    .setLastmodifyPassTime(DateUtil.offsetDay(new Date(), -1))
                    .setPassword(SecurityKit.passwordMD5("123456", "admin"))
                    .setSalt("admin")
                    .setStatus(0)
            );
        }
    }
}
